package com.dh.queue;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * 
 * JDK7提供了以下7个阻塞队列：
 * 
 * ArrayBlockingQueue ：由数组结构组成的有界阻塞队列。 LinkedBlockingQueue ：由链表结构组成的有界阻塞队列。
 * PriorityBlockingQueue ：支持优先级排序的无界阻塞队列。 DelayQueue：使用优先级队列实现的无界阻塞队列。
 * SynchronousQueue：不存储元素的阻塞队列。 LinkedTransferQueue：链表结构组成的无界阻塞队列。
 * LinkedBlockingDeque：链表结构组成的双向阻塞队列。
 * 
 * 
 * 阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构，
 * BlockingQueue提供了线程安全的队列访问方式：当阻塞队列进行插入数据时， 如果队列已满，线程将会阻塞等待直到队列非满；从阻塞队列取数据时，
 * 如果队列已空，线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。
 * 
 * @author liguobao
 *
 */
public class BlockingQueueTest {
	// final成员变量表示常量，只能被赋值一次，赋值后值不再改变。
	private static final int queueSize = 5;
	private static final ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(queueSize);
	private static final int produceSpeed = 2000;// 生产速度(越小越快)
	private static final int consumeSpeed = 10;// 消费速度(越小越快)

	// 生产者
	public static class Producer implements Runnable {
		
		private String name;
		public Producer(String name) {
			this.name=name;
		}
		@Override
		public void run() {
			while (true) {
				try {
					//System.out.println(name+"老板准备炸油条了，架子上还能放：" + (queueSize - queue.size()) + "根油条");
					queue.put("1根油条");
					System.out.println(name+"老板炸好了1根油条，架子上还能放：" + (queueSize - queue.size()) + "根油条");
					Thread.sleep(produceSpeed);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// 消费者
	public static class Consumer implements Runnable {

		@Override
		public void run() {
			while (true) {
				try {
					System.out.println("A 准备买油条了，架子上还剩" + queue.size() + "根油条");
					queue.take();
					System.out.println("取出了" + queue.take());
					System.out.println("A 买到1根油条，架子上还剩" + queue.size() + "根油条");
					Thread.sleep(consumeSpeed);

					System.out.println("B 准备买油条了，架子上还剩" + queue.size() + "根油条");
					queue.take();
					System.out.println("B 买到1根油条，架子上还剩" + queue.size() + "根油条");
					Thread.sleep(consumeSpeed);

					System.out.println("C 准备买油条了，架子上还剩" + queue.size() + "根油条");
					queue.take();
					System.out.println("C 买到1根油条，架子上还剩" + queue.size() + "根油条");
					Thread.sleep(consumeSpeed);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void main(String[] args) {
		Thread producer1 = new Thread(new Producer("张三"));
		Thread producer2 = new Thread(new Producer("李四"));
		Thread consumer = new Thread(new Consumer());
		producer1.start();
		producer2.start();
		consumer.start();
	}

}
